package com.gitee.linzl.zuul.gateway.fiters.routes;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.netflix.hystrix.exception.HystrixTimeoutException;

import lombok.extern.slf4j.Slf4j;

/**
 * 服务的异常退回处理类
 */
@Component
@Slf4j
public class SpringAopIocFallback implements FallbackProvider {

	@Override
	public String getRoute() {
		return "spring-aop-ioc";
	}

	@Override
	public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
		log.error("熔断响应:{}", route);
		// 标记不同的异常为不同的http状态值
		if (cause instanceof HystrixTimeoutException) {
			return response(HttpStatus.GATEWAY_TIMEOUT);
		} else {
			// 可继续添加自定义异常类
			return response(HttpStatus.INTERNAL_SERVER_ERROR);
		}
	}

	// 处理
	private ClientHttpResponse response(final HttpStatus status) {
		log.error("熔断响应status:{}", status);
		return new ClientHttpResponse() {
			@Override
			public HttpStatus getStatusCode() throws IOException {
				return status;
			}

			@Override
			public int getRawStatusCode() throws IOException {
				return status.value();
			}

			@Override
			public String getStatusText() throws IOException {
				return status.getReasonPhrase();
			}

			@Override
			public void close() {
			}

			@Override
			public InputStream getBody() throws IOException {
				// 可替换成相应的json串的 看业务规定了
				JSONObject error = new JSONObject();
				error.put("errCode", "9999");
				error.put("errMsg", "服务暂时不可用");
				return new ByteArrayInputStream(error.toJSONString().getBytes());
			}

			@Override
			public HttpHeaders getHeaders() {
				HttpHeaders headers = new HttpHeaders();
				headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
				return headers;
			}
		};
	}
}
